package personal.jinhui.paprika.service;

import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smackx.pubsub.AccessModel;
import org.jivesoftware.smackx.pubsub.ConfigureForm;
import org.jivesoftware.smackx.pubsub.FormType;
import org.jivesoftware.smackx.pubsub.LeafNode;
import org.jivesoftware.smackx.pubsub.Node;
import org.jivesoftware.smackx.pubsub.PayloadItem;
import org.jivesoftware.smackx.pubsub.PubSubManager;
import org.jivesoftware.smackx.pubsub.SimplePayload;
import org.jivesoftware.smackx.pubsub.Subscription;

import personal.jinhui.paprika.utils.PresenceType;

import android.net.Uri;
import android.os.RemoteException;
import android.util.Log;

import personal.jinhui.paprika.service.aidl.IChatManager;
import personal.jinhui.paprika.service.aidl.IPrivacyListManager;
import personal.jinhui.paprika.service.aidl.IRoster;
import personal.jinhui.paprika.service.aidl.IXmppConnection;
import personal.jinhui.paprika.service.aidl.IXmppFacade;
import personal.jinhui.paprika.smack.avatar.AvatarManager;
import personal.jinhui.paprika.smack.pep.PepSubManager;

/**
 * This class is a facade for the Paprika Service.
 */
public class XmppFacade extends IXmppFacade.Stub {

	private final XmppConnectionAdapter mConnection;

	/**
	 * Constructor for XMPPFacade.
	 * 
	 * @param connection
	 *            the connection use by the facade
	 */
	public XmppFacade(final XmppConnectionAdapter connection) {
		this.mConnection = connection;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void changeStatus(int status, String msg) {
		mConnection.changeStatus(status, msg);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void connectAsync() throws RemoteException {
		mConnection.connectAsync();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void connectSync() throws RemoteException {
		mConnection.connectSync();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public IXmppConnection createConnection() throws RemoteException {
		return mConnection;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void disconnect() throws RemoteException {
		mConnection.disconnect();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public IChatManager getChatManager() throws RemoteException {
		return mConnection.getChatManager();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public IRoster getRoster() throws RemoteException {
		return mConnection.getRoster();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public IPrivacyListManager getPrivacyListManager() {
		return mConnection.getPrivacyListManager();
	}

	@Override
	public void sendPresencePacket(PresenceAdapter presence)
			throws RemoteException {
		Presence presence2 = new Presence(
				PresenceType.getPresenceTypeFrom(presence.getType()));
		presence2.setTo(presence.getTo());
		mConnection.getAdaptee().sendPacket(presence2);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * personal.jinhui.paprika.service.aidl.IXmppFacade#call(java.lang.String)
	 */
	@Override
	public void call(String jid) throws RemoteException {
	}

	@Override
	public void publishAvatar(Uri avatarUri) {
		PaprikaAvatarManager mgr = mConnection.getAvatarManager();
		if (mgr != null)
			mgr.publishAvatar(avatarUri);
	}

	@Override
	public void disableAvatarPublishing() throws RemoteException {
		AvatarManager mgr = mConnection.getAvatarManager();
		if (mgr != null)
			mgr.disableAvatarPublishing();
	}

	@Override
	public void publishLocation(String data) throws RemoteException {

		ConfigureForm form = new ConfigureForm(FormType.submit);
		form.setPersistentItems(false);
		form.setDeliverPayloads(true);
		form.setAccessModel(AccessModel.open);

		PubSubManager manager = new PubSubManager(mConnection.getAdaptee(),
				"pubsub.my.openfire.server");
		Node myNode = null;
		try {
			myNode = manager.createNode("TestNode", form);
		} catch (XMPPException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		SimplePayload payload = new SimplePayload("book", "pubsub:test:book",
				"<book xmlns='pubsub:test:book'><title>Lord of the Rings</title></book>");
		PayloadItem<SimplePayload> item = new PayloadItem<SimplePayload>("999",
				payload);

		// Required to recieve the events being published
		// myNode.addItemEventListener(myEventHandler);

		// Publish item
		((LeafNode) myNode).publish(item);
	}

	@Override
	public void subscribeLocation() throws RemoteException {
		PepSubManager mPep = mConnection.getPep();
		LeafNode node = mPep.getPEPNode("urn:xmpp:location:data");
		try {
			Subscription sp = node.subscribe(getUserInfo().getJid());
			Log.d("##########", "subscribe");
			Log.d("##########", sp.isConfigRequired() + "");
			Log.d("##########", sp.getJid());
			Log.d("##########", sp.getNode());
			Log.d("##########", sp.getId());
			// Log.d("##########", sp.getState());
		} catch (XMPPException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public UserInfo getUserInfo() throws RemoteException {
		return mConnection.getUserInfo();
	}
}
